# coding:utf-8
import uuid
from typing import Union

from PySide6.QtCore import Qt, Signal, QFileInfo
from PySide6.QtGui import QIcon, QImage, QPixmap
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget, QFileIconProvider
from qfluentwidgets import (setFont, ProgressBar, IconWidget, FluentIconBase, FluentIcon as FIF, Action,
                            BodyLabel as BL)
from qfluentwidgets.components.material import AcrylicMenu

from common import SingleIcon, TaskMessage, TaskStatus, Task, TaskDao, cfg, COVER_DIR
from threads import StreamRunner, M3u8Runner, send_sql_request
from ..dialog import TextDialog, DeleteDialog
from ..widgets import (ImageLabel, CustomSimpleCardWidget, BodyLabel)


class InfoWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.horizontalLayout = QHBoxLayout(self)
        self.statusIcon = self.creatIcon(FIF.PENCIL_INK)
        self.statusLabel = self.createLabel('状态: 等待中')
        self.progressIcon = self.creatIcon(FIF.BOOK_SHELF)
        self.progressLabel = self.createLabel('进度: 0%')
        self.speedIcon = self.creatIcon(FIF.SPEED_MEDIUM)
        self.speedLabel = self.createLabel('速度: 0 / 0')
        self.infoIcon = self.creatIcon(FIF.INFO)
        self.infoLabel = self.createLabel('日志: 暂无日志')

        self.horizontalLayout.setAlignment(Qt.AlignmentFlag.AlignLeft)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setSpacing(10)
        self.horizontalLayout.addWidget(self.statusIcon, 0)
        self.horizontalLayout.addWidget(self.statusLabel, 0)
        self.horizontalLayout.addWidget(self.progressIcon, 0)
        self.horizontalLayout.addWidget(self.progressLabel, 0)
        self.horizontalLayout.addWidget(self.speedIcon, 0)
        self.horizontalLayout.addWidget(self.speedLabel, 0)
        self.horizontalLayout.addWidget(self.infoIcon, 0)
        self.horizontalLayout.addWidget(self.infoLabel, 0)

    def creatIcon(self, icon: Union[str, QIcon, FluentIconBase]):
        label = IconWidget(self)
        label.setIcon(icon)
        label.setFixedSize(14, 14)
        return label

    def createLabel(self, text: str):
        label = BL(text, self)
        setFont(label, 12)
        return label


class TaskCard(CustomSimpleCardWidget):
    deleteTaskSig = Signal(object)

    def __init__(self, runner: Union[StreamRunner, M3u8Runner], parent=None):
        super().__init__(parent)
        self.runner = runner
        self.status = TaskStatus.WAIT
        self.taskMsg = TaskMessage()
        self.task = None

        self.verticalLayout = QVBoxLayout(self)
        self.horizontalLayout = QHBoxLayout()
        self.verticalLayout_2 = QVBoxLayout()
        self.coverLabel = ImageLabel(SingleIcon.COVER.path(), self)
        self.titleLabel = BodyLabel('文件名称', self)
        self.infoWidget = InfoWidget(self)
        self.progressBar = ProgressBar(self)

        self.__initWidgets()

    def __initWidgets(self):
        self.coverLabel.setFixedSize(60, 60)
        self.coverLabel.setRadius(5)
        self.setFixedHeight(90)
        self.setMinimumWidth(500)
        setFont(self.titleLabel, 16)

        self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        self.__initLayout()

    def __initLayout(self):
        self.verticalLayout.setContentsMargins(10, 10, 10, 10)

        self.horizontalLayout.setAlignment(Qt.AlignmentFlag.AlignLeft)
        self.horizontalLayout.addWidget(self.coverLabel)
        self.horizontalLayout.addSpacing(10)

        self.verticalLayout_2.setAlignment(Qt.AlignmentFlag.AlignVCenter)
        self.verticalLayout_2.addWidget(self.titleLabel)
        self.verticalLayout_2.addWidget(self.infoWidget)
        self.horizontalLayout.addLayout(self.verticalLayout_2)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.verticalLayout.addWidget(self.progressBar)

    def showContextMenu(self, pos):
        menu = AcrylicMenu(parent=self)
        if self.status == TaskStatus.PAUSE:
            menu.addAction(Action(FIF.PLAY, '开始/继续', self, triggered=self.start))
        elif self.status == TaskStatus.DOING:
            menu.addAction(Action(FIF.PAUSE, '暂停', self, triggered=self.stop))
        elif self.status == TaskStatus.ERROR:
            menu.addAction(Action(FIF.UPDATE, '重新下载', self, triggered=self.start))
        menu.addAction(Action(FIF.DELETE, '删除', self, triggered=self._deleteTask))
        menu.addAction(Action(FIF.INFO, '错误信息', self, triggered=self._onShowError))
        menu.exec(self.mapToGlobal(pos))

    def _onShowError(self):
        dialog = TextDialog(self.tr('错误信息'), self.window())
        dialog.setText(self.taskMsg.error_msg)
        dialog.exec()

    def _deleteTask(self):
        if not self.task:
            return
        dialog = DeleteDialog(self.window())
        if dialog.exec():
            self.stop()
            send_sql_request(
                lambda session: TaskDao.delete_by_id(
                    self.task.id,
                    session,
                    delete_file=dialog.isChecked()
                )
            )
            self.deleteTaskSig.emit(self)

    def stop(self):
        if self.runner:
            self.runner.stop()

    def start(self):
        self.infoWidget.infoLabel.setText('等待中...')
        self.progressBar.setValue(0)
        self.infoWidget.statusLabel.setText(TaskStatus.WAIT.value)
        self.infoWidget.speedLabel.setText('0MB/S')
        self.infoWidget.progressLabel.setText('0MB / 0MB')

        self.runner = self.runner.start()

    def setTitle(self, title: str):
        self.titleLabel.setText(title)

    def setTask(self, task: Task):
        self.task = task
        status = TaskStatus.str_to(task.status)
        if not status:
            status = TaskStatus.PAUSE
        if task.cover:
            self.coverLabel.setImage(task.cover)
        else:
            pixmap = QFileIconProvider().icon(
                QFileInfo(task.file_name)
            ).pixmap(60, 60)
            self.coverLabel.setImage(pixmap)
        self.setTaskMessage(
            TaskMessage(
                id=task.id,
                message=task.file_name,
                progress=task.progress,
                status=status,
                downloaded_msg=task.size,
            ), False
        )

    def setTaskMessage(self, taskMsg: TaskMessage, update: bool = True):
        status = taskMsg.status
        self.status = status
        self.taskMsg = taskMsg

        self.infoWidget.infoLabel.setText(taskMsg.message)
        self.progressBar.setValue(int(taskMsg.progress))
        self.infoWidget.statusLabel.setText(taskMsg.status.value)
        self.infoWidget.speedLabel.setText(taskMsg.net_speed)
        self.infoWidget.progressLabel.setText(taskMsg.downloaded_msg)

        if status in [TaskStatus.PAUSE, TaskStatus.ERROR]:
            self.progressBar.setPaused(True)
            self.infoWidget.speedLabel.setText('0MB/S')
        else:
            self.progressBar.setPaused(False)
        if status == TaskStatus.DONE:
            self.progressBar.setVisible(False)
        else:
            self.progressBar.setVisible(True)
        # 停止时保存进度
        if not update:
            return
        if status in [TaskStatus.PAUSE, TaskStatus.DONE, TaskStatus.ERROR, TaskStatus.CANCEL]:
            cover = taskMsg.cover
            self.coverLabel.setImage(cover)
            send_sql_request(
                TaskDao.update_by_id,
                ts := Task(
                    id=taskMsg.id,
                    status=taskMsg.status.value,
                    progress=taskMsg.progress,
                    size=taskMsg.downloaded_msg,
                    cover=cover
                )
            )
            # print(ts)
